package org.richin.lang.util;

import java.io.UnsupportedEncodingException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.URL;
import java.net.URLEncoder;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.apache.log4j.Logger;
import org.omg.CosNaming.NamingContextPackage.NotEmpty;
import org.richin.array.util.ArrayUtils;
import org.richin.collection.util.ListUtils;
import org.richin.servlet.util.RequestUtils;

import com.sun.istack.internal.FinalArrayList;

public class StringUtils extends org.apache.commons.lang.StringUtils {
	private final static Logger log = Logger.getLogger(StringUtils.class);
	private static final String _BR = "<br/>";
	private static String[] _BOOLEANS = { "true", "t", "y", "on", "1" };

	public static boolean isChinese(String str) {
		Pattern pattern = Pattern.compile("[\u0391-\uFFE5]+$");
		return pattern.matcher(str).matches();
	}
	/**
	 * 大段文本的快速替换(么测试)
	 * @param strSource
	 * @param strOld
	 * @param strNew
	 * @return
	 */
	public static String Replace(String strSource, String strOld, String strNew) {
		int index, indexStart;
		StringBuffer strDest = new StringBuffer(0);
		int nOldLength = strOld.length();
		if (isEmpty(strOld))
			return strSource;
		index = strSource.indexOf(strOld);
		if (index == -1)
			return strSource;
		strDest.append(strSource.substring(0, index) + strNew);
		indexStart = index + nOldLength;
		while ((index = strSource.indexOf(strOld, indexStart)) != -1) {
			strDest.append(strSource.substring(indexStart, index) + strNew);
			indexStart = index + nOldLength;
		}
		strDest.append(strSource.substring(indexStart));
		return strDest.toString();
	}
	/**
	 * Convenience method to return a Collection as a CSV String.
	 * E.g. useful for toString() implementations.
	 * @param coll Collection to display
	 */
	public static String collectionToCommaDelimitedString(Collection coll) {
		return collectionToDelimitedString(coll, ",");
	}

	/**
	 * Convenience method to return a Collection as a delimited (e.g. CSV)
	 * String. E.g. useful for toString() implementations.
	 * @param coll Collection to display
	 * @param delim delimiter to use (probably a ",")
	 */
	public static String collectionToDelimitedString(Collection coll, String delim) {
		return collectionToDelimitedString(coll, delim, "", "");
	}

	/**
	 * Convenience method to return a Collection as a delimited (e.g. CSV)
	 * String. E.g. useful for toString() implementations.
	 * @param coll Collection to display
	 * @param delim delimiter to use (probably a ",")
	 * @param prefix string to start each element with
	 * @param suffix string to end each element with
	 */
	public static String collectionToDelimitedString(Collection coll, String delim, String prefix, String suffix) {
		if (coll == null) {
			return "";
		}

		StringBuffer sb = new StringBuffer();
		Iterator it = coll.iterator();
		int i = 0;
		while (it.hasNext()) {
			if (i > 0) {
				sb.append(delim);
			}
			sb.append(prefix).append(it.next()).append(suffix);
			i++;
		}
		return sb.toString();
	}

	public static String format(String pattern, Object... values) {
		MessageFormat messageFormat = new MessageFormat(pattern);
		return (messageFormat.format(values));
	}

	public static boolean hasLength(CharSequence str) {
		return str != null && str.length() > 0;
	}

	public static boolean containsWhitespace(String str) {
		if (!hasLength(str))
			return false;
		int strLen = str.length();
		for (int i = 0; i < strLen; i++) {
			if (Character.isWhitespace(str.charAt(i))) {
				return true;
			}
		}
		return false;
	}

	public static boolean containsUpperChar(String str) {
		for (int i = 0; i < str.length(); i++) {
			if (Character.isUpperCase(str.charAt(i))) {
				return true;
			}
		}
		return false;
	}

	public static String deleteWhitespace(String str) {
		if (!hasLength(str))
			return str;
		int sz = str.length();
		char[] chs = new char[sz];
		int count = 0;
		for (int i = 0; i < sz; i++) {
			if (!Character.isWhitespace(str.charAt(i))) {
				chs[count++] = str.charAt(i);
			}
		}
		return count == sz ? str : new String(chs, 0, count);
	}

	public static String trimWhitespace(String str) {
		if (!hasLength(str))
			return str;
		StringBuilder sb = new StringBuilder(str);
		while (sb.length() > 0 && Character.isWhitespace(sb.charAt(0))) {
			sb.deleteCharAt(0);
		}
		while (sb.length() > 0 && Character.isWhitespace(sb.charAt(sb.length() - 1))) {
			sb.deleteCharAt(sb.length() - 1);
		}
		return sb.toString();
	}

	/**
	* 去除字符串两边的自定义特殊字符
	*
	* @param str
	* @param ch
	* @return String
	*/
	public static String trim(String str, String ch) {

		int index = str.indexOf(ch);
		if (index == 0) {
			str = str.substring(ch.length());
		}
		index = str.lastIndexOf(ch);
		if (index == str.length() - ch.length()) {
			str = str.substring(0, index);
		}
		return str;
	}

	public static String trimLeft(String s, char c) {
		int len = s.length();
		int st = 0;
		char[] val = s.toCharArray();

		// Trim left
		while ((st < len) && (val[st] == c)) {
			st++;
		}

		return ((st > 0) || (len < s.length())) ? s.substring(st, len) : s;
	}

	public static String trimRight(String s, char c) {
		int len = s.length();
		int st = 0;
		char[] val = s.toCharArray();

		while ((st < len) && (val[len - 1] == c)) {
			len--;
		}

		return ((st > 0) || (len < s.length())) ? s.substring(st, len) : s;
	}

	/**
	 * Replaces all matches with another
	 *
	 * @param buffer to be altered
	 * @param s1 which is replaced by s2
	 * @param s2 which replaces s1
	 * @return Altered buffer
	 */

	public static String replaceMatches(String buffer, String s1, String s2) {
		int pos, from = 0;
		StringBuffer line = new StringBuffer();
		// Replace, until ready
		for (;;) {
			pos = buffer.indexOf(s1, from);
			if (pos != -1) {
				line.append(buffer.substring(from, pos));
				line.append(s2);
				from = pos + s1.length();
			} else {
				line.append(buffer.substring(from, buffer.length()));
				break;
			}
		}
		return line.toString();
	}

	/**
	 * Replaces a string between two tags.
	 *
	 * @param buffer to be altered.
	 * @param insert to be replaced into between the tags.
	 * @param tag1 start tag.
	 * @param replace1 When true, does replace tag1 too.
	 * @param tag2 end tag.
	 * @param replace2 When true, does replace tag2 too.
	 * @param all When true, all matches in the text are replaced, not only the first one.
	 * @return Altered buffer.
	 */
	public static String replaceBetween(String buffer, String insert, String tag1, boolean replace1, String tag2,
			boolean replace2, boolean all) {
		int pos1 = 0;
		// Replace, until ready.
		for (;;) {
			// Starting position
			pos1 = buffer.indexOf(tag1, pos1);
			if (pos1 == -1) {
				return buffer;
			}
			if (!replace1) {
				pos1 += tag1.length();
			}
			// Ending position
			int pos2 = buffer.indexOf(tag2, pos1);
			if (pos2 == -1) {
				return buffer;
			}
			if (replace2) {
				pos2 += tag2.length();
			}
			// Replace tagged area
			StringBuffer new_buffer = new StringBuffer();
			new_buffer.append(buffer);
			new_buffer.replace(pos1, pos2, insert);
			if (!all) {
				return new_buffer.toString();
			} else {
				buffer = new_buffer.toString();
			}
		}
	}

	/**
	 * Replaces a string between two tags.
	 *
	 * @param buffer to be altered.
	 * @param insert to be replaced into between the tags.
	 * @param tag1 start tag.
	 * @param tag2 end tag.
	 * @param all When true, all matches in the text are replaced, not only the first one.
	 * @return Altered buffer.
	 */
	public static String replaceBetween(String buffer, String insert, String tag1, String tag2, boolean all) {
		return replaceBetween(buffer, insert, tag1, false, tag2, false, all);
	}

	/**
	 * Replaces a string between two tags.
	 *
	 * @param buffer to be altered.
	 * @param insert to be replaced into between the tags.
	 * @param tag1 start tag.
	 * @param tag2 end tag.
	 * @return Altered buffer.
	 */
	public static String replaceBetween(String buffer, String insert, String tag1, String tag2) {
		return replaceBetween(buffer, insert, tag1, tag2, true);
	}

	/**
	 * 将指定长度的字母转换为大写
	 *
	 * @param str 需要转换的字符串
	 * @param i 需要转换的长度
	 * @return 转换后的字符
	 */
	public static String toUpperCase(String str, int i) {
		return str.substring(0, i).toUpperCase() + str.substring(i);
	}

	/**
	 * 将指定长度的字母转换为小写
	 *
	 * @param str 需要转换的字符串
	 * @param i 需要转换的长度
	 * @return 转换后的字符
	 */
	public static String toLowerCase(String str, int i) {
		return str.substring(0, i).toLowerCase() + str.substring(i);
	}

	public static boolean hasLength(String str) {
		return hasLength(((CharSequence) (str)));
	}

	public static String trimAllWhitespace(String str) {
		if (!hasLength(str))
			return str;
		StringBuffer buf = new StringBuffer(str);
		for (int index = 0; buf.length() > index;)
			if (Character.isWhitespace(buf.charAt(index)))
				buf.deleteCharAt(index);
			else
				index++;

		return buf.toString();
	}

	/**
	* Substitutes <code>searchString</code> in the given source String with <code>replaceString</code>.<p>
	*
	* This is a high-performance implementation which should be used as a replacement for
	* <code>{@link String#replaceAll(java.lang.String, java.lang.String)}</code> in case no
	* regular expression evaluation is required.<p>
	*
	* @param source the content which is scanned
	* @param searchString the String which is searched in content
	* @param replaceString the String which replaces <code>searchString</code>
	*
	* @return the substituted String
	*/
	public static String substitute(String source, String searchString, String replaceString) {

		if (source == null) {
			return null;
		}

		if (isEmpty(searchString)) {
			return source;
		}

		if (replaceString == null) {
			replaceString = "";
		}
		int len = source.length();
		int sl = searchString.length();
		int rl = replaceString.length();
		int length;
		if (sl == rl) {
			length = len;
		} else {
			int c = 0;
			int s = 0;
			int e;
			while ((e = source.indexOf(searchString, s)) != -1) {
				c++;
				s = e + sl;
			}
			if (c == 0) {
				return source;
			}
			length = len - (c * (sl - rl));
		}

		int s = 0;
		int e = source.indexOf(searchString, s);
		if (e == -1) {
			return source;
		}
		StringBuffer sb = new StringBuffer(length);
		while (e != -1) {
			sb.append(source.substring(s, e));
			sb.append(replaceString);
			s = e + sl;
			e = source.indexOf(searchString, s);
		}
		e = len;
		sb.append(source.substring(s, e));
		return sb.toString();
	}

	/** 
	* 转码：GBK ----> iso-8859-1 
	* @param s 转码字段 
	* @return 转码后的字段 
	*/
	public static String GBKtoISO(String s) {
		try {
			s = new String(s.getBytes("GBK"), "iso-8859-1");
		} catch (Exception e) {
		}
		return s;
	}

	/**
	 * 将字符串转义以方便html输出
	 */
	public static String escapeHtml(String s) {
		return org.apache.commons.lang.StringEscapeUtils.escapeHtml(s);
	}

	/**
	 * 将指定字符串重复n遍。
	 * 
	 * <pre>
	 *   
	 *    StringUtil.repeat(null, 2)   = null
	 *    StringUtil.repeat(&quot;&quot;, 0)     = &quot;&quot;
	 *    StringUtil.repeat(&quot;&quot;, 2)     = &quot;&quot;
	 *    StringUtil.repeat(&quot;a&quot;, 3)    = &quot;aaa&quot;
	 *    StringUtil.repeat(&quot;ab&quot;, 2)   = &quot;abab&quot;
	 *    StringUtil.repeat(&quot;abcd&quot;, 2) = &quot;abcdabcd&quot;
	 *    StringUtil.repeat(&quot;a&quot;, -2)   = &quot;&quot;
	 *    
	 * </pre>
	 * 
	 * @param str
	 *            要重复的字符串
	 * @param repeat
	 *            重复次数，如果小于 <code>0</code> ，则看作 <code>0</code>
	 * 
	 * @return 重复n次的字符串，如果原始字符串为 <code>null</code> ，则返回 <code>null</code>
	 */
	public static String repeat(String str, int repeat) {
		if (str == null) {
			return null;
		}

		if (repeat <= 0) {
			return EMPTY;
		}

		int inputLength = str.length();

		if ((repeat == 1) || (inputLength == 0)) {
			return str;
		}

		int outputLength = inputLength * repeat;

		switch (inputLength) {
		case 1:

			char ch = str.charAt(0);
			char[] output1 = new char[outputLength];

			for (int i = repeat - 1; i >= 0; i--) {
				output1[i] = ch;
			}

			return new String(output1);

		case 2:

			char ch0 = str.charAt(0);
			char ch1 = str.charAt(1);
			char[] output2 = new char[outputLength];

			for (int i = (repeat * 2) - 2; i >= 0; i--, i--) {
				output2[i] = ch0;
				output2[i + 1] = ch1;
			}

			return new String(output2);

		default:

			StringBuffer buf = new StringBuffer(outputLength);

			for (int i = 0; i < repeat; i++) {
				buf.append(str);
			}

			return buf.toString();
		}
	}

	public static String toUtf8String(String s) {
		StringBuffer sb = new StringBuffer();
		for (int i = 0; i < s.length(); i++) {
			char c = s.charAt(i);
			if (c >= 0 && c <= 255) {
				sb.append(c);
			} else {
				byte[] b;
				try {
					b = Character.toString(c).getBytes("utf-8");
				} catch (Exception ex) {
					b = new byte[0];
				}
				for (int j = 0; j < b.length; j++) {
					int k = b[j];
					if (k < 0)
						k += 256;
					sb.append("%" + Integer.toHexString(k).toUpperCase());
				}
			}
		}
		String s_utf8 = sb.toString();
		sb.delete(0, sb.length());
		sb.setLength(0);
		sb = null;
		return s_utf8;
	}

	/** 
	 * 转码：iso-8859-1 ----> GBK 
	 * @param s 转码字段 
	 * @return 转码后的字段 
	 */
	public static String ISOtoGBK(String s) {
		try {
			s = new String(s.getBytes("iso-8859-1"), "GBK");
		} catch (Exception e) {
		}
		return s;
	}

	/**
	 * 功能描述：判断输入的字符串是否符合Email样式.
	 * 
	 * @param str
	 *            传入的字符串
	 * @return 是Email样式返回true,否则返回false
	 */
	public static boolean isEmail(String email) {
		if (email == null || email.length() < 1 || email.length() > 256)
			return false;
		Pattern pattern = Pattern.compile("^\\w+([-+.]\\w+)*@\\w+([-.]\\w+)*\\.\\w+([-.]\\w+)*$");
		return pattern.matcher(email).matches();
	}

	/**
	 * 判断是否为整数
	 * 
	 * @param str 传入的字符串
	 * @return 是整数返回true,否则返回false
	 */
	public static boolean isInteger(String str) {
		Pattern pattern = Pattern.compile("^[-\\+]?[\\d]*$");
		return pattern.matcher(str).matches();
	}

	/**
	  * 字符串是否由0-9这十个字符组成
	  * 
	  * @param sNumber
	  * @return
	  */
	public static boolean isNumeric(String sNumber) {
		/** 为NULL直接返回false */
		if (isEmpty(sNumber))
			return false;
		/** 正则表达式验测字符串 */
		if (sNumber.matches("^\\d+$"))
			return true;
		return false;
	}

	/**
	 * 判断此字符串是否为空、空字符串，或"null"
	 * 
	 * <pre>
	 * StringUtil.isNullStr(null)      = true
	 * StringUtil.isNullStr( )        = true
	 * StringUtil.isNullStr(   )       = true
	 * StringUtil.isNullStr( null )       = true
	 * StringUtil.isNullStr( bob )     = false
	 * StringUtil.isNullStr(   bob   ) = false
	 * </pre>
	 * 
	 * @param str
	 * @return
	 */
	public static boolean isNullStr(String str) {
		if (str == null) {
			return true;
		}
		str = str.trim();
		return ("null".equals(str) || str.length() == 0);
	}

	public static boolean isNotNullStr(String str) {

		return !isNullStr(str);
	}

	/**
	 * 将GBK转化为ISO-8859-1
	 * 
	 * @param para
	 * @return
	 */
	public static String gbkToIso(String str) {
		try {
			return new String(str.getBytes("GBK"), "ISO-8859-1");
		} catch (UnsupportedEncodingException e) {
			return "";
		} catch (Exception e) {
			return "";
		}
	}

	/**
	 * 判断字符串中是否有中文
	 * 
	 * @param str
	 * @return
	 */
	public static boolean isContainChinaStr(String str) {
		if (str == null || str.length() == gbkToIso(str).length())
			return false;
		return true;

	}

	/**
	 * 将一个字串的首字母大写
	 * 
	 * @param s
	 *            源字串
	 * @return 首字母大写后的字串
	 */
	public static String capitalize(String s) {
		if (s == null || s.length() == 0)
			return s;
		else {
			char ac[] = s.toCharArray();
			ac[0] = Character.toUpperCase(ac[0]);
			return new String(ac);
		}
	}

	/**
	 * 
	 * 中文转换--文章换行的转换
	 * 
	 * @param str
	 * 
	 * @return
	 * 
	 */

	public static String getText(String str) {
		if (isEmpty(str))
			return ("");

		// 建立一个StringBuffer来处理输入数据
		StringBuilder buf = new StringBuilder(str.length() + 6);
		char ch = '\n';
		for (int i = 0; i < str.length(); i++) {
			ch = str.charAt(i);
			if (ch == '\n') {
				buf.append("<br>");
			} else if (ch == '\t') {
				buf.append("    ");
			} else if (ch == ' ') {
				buf.append(" ");
			} else {
				buf.append(ch);
			}
		}
		return buf.toString();
	}

	/**
	 * 
	 * 截取一定长度字符串，用于页面显示，如果长度超出截取部分，用
	 * 
	 * postfix续尾
	 * 
	 * 
	 * 
	 * @param 原始字符串
	 * 
	 * @param 开始位置
	 * 
	 * @param 结束位置
	 * 
	 * @param postfix
	 *            超长部分使用postfix参数结尾
	 * 
	 * @return 返回转换后的字符串
	 * 
	 */

	public static String subPostfix(String str, int start, int end, String postfix) {
		if (isNullStr(str))
			return EMPTY;
		int length = str.length();
		if (length <= start)
			return str;
		else if (length <= end)
			return str.substring(start, length);
		else
			return str.substring(start, end) + postfix;
	}

	/**
	 * 字符串截取避免截取半个中文字符
	 * 
	 * @param str
	 * @param begin
	 * @param end
	 * @return
	 */
	public static String cutString(String str, int begin, int end) {
		if (org.apache.commons.lang.StringUtils.isEmpty(str))
			return str;
		char[] b = str.toCharArray();
		String s = new String(b, begin, end - begin);

		return s;
	}

	public static String cutString(String str, int length) {
		return cutString(str, 0, length);
	}

	/**
	 * 正则替换字符串里面的汉字部分。
	 * 
	 * @param str
	 *            被替换的字符串
	 * @param charset
	 *            字符集
	 * @return 替换好的
	 * 
	 */
	public static String encode(String str, String charset) {
		Pattern p = Pattern.compile("[\u4e00-\u9fa5]+");
		Matcher m = p.matcher(str);
		StringBuffer b = new StringBuffer();
		try {
			while (m.find()) {
				m.appendReplacement(b, URLEncoder.encode(m.group(0), charset));
			}
		} catch (UnsupportedEncodingException e) {
			System.out.println("转换错误");
		}
		m.appendTail(b);
		return b.toString();
	}

	/**
	 * 功能描述：替换字符串
	 * 
	 * @param from
	 *            String 原始字符串
	 * @param to
	 *            String 目标字符串
	 * @param source
	 *            String 母字符串
	 * @return String 替换后的字符串
	 */
	public static String replace(String from, String to, String source) {
		if (source == null || from == null || to == null)
			return null;
		StringBuffer str = new StringBuffer("");
		int index = -1;
		while ((index = source.indexOf(from)) != -1) {
			str.append(source.substring(0, index) + to);
			source = source.substring(index + from.length());
			index = source.indexOf(from);
		}
		str.append(source);
		return str.toString();
	}
	/**
	 * 清空字符串中的空格,制表符等
	 * @param applyData
	 * @return
	 */
	public static String replaceBlank(String applyData) {
		Pattern p = Pattern.compile("\\s*|\\t|\\r|\\n");
		Matcher m = p.matcher(applyData);
		return m.replaceAll("");
	}
	/**
	 * 替换字符串，能能够在HTML页面上直接显示(替换双引号和小于号)
	 * 
	 * @param str
	 *            String 原始字符串
	 * @return String 替换后的字符串
	 */
	public static String htmlencode(String str) {
		if (str == null)
			return null;
		return replace("\"", "&quot;", replace("<", "&lt;", str));
	}

	/**
	 * 替换字符串，将被编码的转换成原始码（替换成双引号和小于号）
	 * 
	 * @param str
	 *            String
	 * @return String
	 */
	public static String htmldecode(String str) {
		if (str == null)
			return null;

		return replace("&quot;", "\"", replace("&lt;", "<", str));
	}

	/**
	 * 功能描述：在页面上直接显示文本内容，替换小于号，空格，回车，TAB
	 * 
	 * @param str
	 *            String 原始字符串
	 * @return String 替换后的字符串
	 */
	public static String htmlshow(String str) {
		if (str == null)
			return null;

		str = replace("<", "&lt;", str);
		str = replace(" ", "&nbsp;", str);
		str = replace("\r\n", _BR, str);
		str = replace("\n", _BR, str);
		str = replace("\t", "&nbsp;&nbsp;&nbsp;&nbsp;", str);
		return str;
	}

	/**
	 * 判断是不是合法字符 c 要判断的字符
	 */
	public static boolean isLetter(String str) {
		if (str == null || str.length() < 0)
			return false;
		Pattern pattern = Pattern.compile("[\\w\\.-_]*");
		return pattern.matcher(str).matches();
	}

	/**
	 * 从指定的字符串中提取Email content 指定的字符串
	 * 
	 * @param content
	 * @return
	 */
	public static String parse(String content) {
		String email = null;
		if (content == null || content.length() < 1)
			return email;
		// 找出含有@
		int beginPos;
		int i;
		String token = "@";
		String preHalf = "";
		String sufHalf = "";

		beginPos = content.indexOf(token);
		if (beginPos > -1) {
			// 前项扫描
			String s = null;
			i = beginPos;
			while (i > 0) {
				s = content.substring(i - 1, i);
				if (isLetter(s))
					preHalf = s + preHalf;
				else
					break;
				i--;
			}
			// 后项扫描
			i = beginPos + 1;
			while (i < content.length()) {
				s = content.substring(i, i + 1);
				if (isLetter(s))
					sufHalf = sufHalf + s;
				else
					break;
				i++;
			}
			// 判断合法性
			email = preHalf + "@" + sufHalf;
			if (isEmail(email))
				return email;
		}
		return null;
	}

	/**
	 * 功能描述：返回指定字节长度的字符串
	 * 
	 * @param str
	 *            String 字符串
	 * @param length
	 *            int 指定长度
	 * @return String 返回的字符串
	 */
	public static String toLength(String str, int length) {
		if (str == null)
			return null;
		if (length <= 0)
			return "";
		try {
			if (str.getBytes("GBK").length <= length)
				return str;
		} catch (Exception e) {
		}
		StringBuffer buff = new StringBuffer();

		int index = 0;
		char c;
		length -= 3;
		while (length > 0) {
			c = str.charAt(index);
			if (c < 128) {
				length--;
			} else {
				length--;
				length--;
			}
			buff.append(c);
			index++;
		}
		buff.append("...");
		return buff.toString();
	}

	/**
	 * 功能描述：人民币转成大写
	 * 
	 * @param str
	 *            数字字符串
	 * @return String 人民币转换成大写后的字符串
	 */
	public static String hangeToBig(String str) {
		double value;
		try {
			value = Double.parseDouble(str.trim());
		} catch (Exception e) {
			return null;
		}
		char[] hunit = { '拾', '佰', '仟' }; // 段内位置表示
		char[] vunit = { '万', '亿' }; // 段名表示
		char[] digit = { '零', '壹', '贰', '叁', '肆', '伍', '陆', '柒', '捌', '玖' }; // 数字表示
		long midVal = (long) (value * 100); // 转化成整形
		String valStr = String.valueOf(midVal); // 转化成字符串

		String head = valStr.substring(0, valStr.length() - 2); // 取整数部分
		String rail = valStr.substring(valStr.length() - 2); // 取小数部分

		String prefix = ""; // 整数部分转化的结果
		String suffix = ""; // 小数部分转化的结果
		// 处理小数点后面的数
		if (rail.equals("00")) { // 如果小数部分为0
			suffix = "整";
		} else {
			suffix = digit[rail.charAt(0) - '0'] + "角" + digit[rail.charAt(1) - '0'] + "分"; // 否则把角分转化出来
		}
		// 处理小数点前面的数
		char[] chDig = head.toCharArray(); // 把整数部分转化成字符数组
		char zero = '0'; // 标志'0'表示出现过0
		byte zeroSerNum = 0; // 连续出现0的次数
		for (int i = 0; i < chDig.length; i++) { // 循环处理每个数字
			int idx = (chDig.length - i - 1) % 4; // 取段内位置
			int vidx = (chDig.length - i - 1) / 4; // 取段位置
			if (chDig[i] == '0') { // 如果当前字符是0
				zeroSerNum++; // 连续0次数递增
				if (zero == '0') { // 标志
					zero = digit[0];
				} else if (idx == 0 && vidx > 0 && zeroSerNum < 4) {
					prefix += vunit[vidx - 1];
					zero = '0';
				}
				continue;
			}
			zeroSerNum = 0; // 连续0次数清零
			if (zero != '0') { // 如果标志不为0,则加上,例如万,亿什么的
				prefix += zero;
				zero = '0';
			}
			prefix += digit[chDig[i] - '0']; // 转化该数字表示
			if (idx > 0)
				prefix += hunit[idx - 1];
			if (idx == 0 && vidx > 0) {
				prefix += vunit[vidx - 1]; // 段结束位置应该加上段名如万,亿
			}
		}

		if (prefix.length() > 0)
			prefix += '圆'; // 如果整数部分存在,则有圆的字样
		return prefix + suffix; // 返回正确表示
	}

	/**
	 * 功能描述：去掉字符串中重复的子字符串
	 * 
	 * @param str
	 *            原字符串，如果有子字符串则用空格隔开以表示子字符串
	 * @return String 返回去掉重复子字符串后的字符串
	 */
	@SuppressWarnings("unused")
	private static String removeSameString(String str) {
		return removeSameString(str, " ");
	}

	private static String removeSameString(String str, String split) {
		Set<String> mLinkedSet = new LinkedHashSet<String>();
		String[] strArray = str.split(split);
		StringBuffer sb = new StringBuffer();

		for (int i = 0; i < strArray.length; i++) {
			if (!mLinkedSet.contains(strArray[i])) {
				mLinkedSet.add(strArray[i]);
				sb.append(strArray[i] + " ");
			}
		}
		System.out.println(mLinkedSet);
		return sb.toString().substring(0, sb.toString().length() - 1);
	}

	/**
	 * 功能描述：过滤特殊字符
	 * 
	 * @param src
	 * @return
	 */
	public static String encoding(String src) {
		if (src == null)
			return "";
		StringBuilder result = new StringBuilder();
		if (src != null) {
			src = src.trim();
			for (int pos = 0; pos < src.length(); pos++) {
				switch (src.charAt(pos)) {
				case '\"':
					result.append("&quot;");
					break;
				case '<':
					result.append("&lt;");
					break;
				case '>':
					result.append("&gt;");
					break;
				case '\'':
					result.append("&apos;");
					break;
				case '&':
					result.append("&amp;");
					break;
				case '%':
					result.append("&pc;");
					break;
				case '_':
					result.append("&ul;");
					break;
				case '#':
					result.append("&shap;");
					break;
				case '?':
					result.append("&ques;");
					break;
				default:
					result.append(src.charAt(pos));
					break;
				}
			}
		}
		return result.toString();
	}

	/**
	 * 功能描述：反过滤特殊字符
	 * 
	 * @param src
	 * @return
	 */
	public static String decoding(String src) {
		if (src == null)
			return "";
		String result = src;
		result = result.replace("&quot;", "\"").replace("&apos;", "\'");
		result = result.replace("&lt;", "<").replace("&gt;", ">");
		result = result.replace("&amp;", "&");
		result = result.replace("&pc;", "%").replace("&ul", "_");
		result = result.replace("&shap;", "#").replace("&ques", "?");
		return result;
	}

	/**
	 * 字符串截取函数
	 * 
	 * @param str
	 *            String 要处理的字符串
	 * @param length
	 *            int 需要显示的长度
	 * @param symbol
	 *            String 用于表示省略的信息的字符，如“...”,“>>>”等
	 * @return String 返回处理后的字符串
	 * @throws UnsupportedEncodingException
	 */
	public static String getLimitLengthString(String str, int length, String symbol)
			throws UnsupportedEncodingException {
		assert str != null;
		assert length > 0;
		assert symbol != null;
		// 如果字符串的位数小于等于要截取的位数，附加上表示省略的信息的字符串后返回
		if (str.length() <= length)
			return str + symbol;
		// 从零开始，截取length个字符，附加上表示省略的信息的字符串后返回
		else {
			str = new String(str.getBytes("GBK"));
			char[] charArray = str.toCharArray();
			char[] charArrayDesc = new char[length];
			System.arraycopy(charArray, 0, charArrayDesc, 0, length);
			return new String(charArrayDesc) + symbol;
		}
	}// System.out.println(getLimitLengthString("如果字符串caace爽肤水水电费是否ttt",10,"..."));

	/**
	 * 按字节长度截取字符串
	 * 
	 * @param str
	 *            将要截取的字符串参数
	 * @param toCount
	 *            截取的字节长度
	 * @param more
	 *            字符串末尾补上的字符串
	 * @return 返回截取后的字符串
	 */
	public static String substring(String str, int toCount, String more) {
		int reInt = 0;
		String reStr = "";
		if (str == null)
			return "";
		char[] tempChar = str.toCharArray();
		for (int kk = 0; (kk < tempChar.length && toCount > reInt); kk++) {
			String s1 = String.valueOf(tempChar[kk]);
			byte[] b = s1.getBytes();
			reInt += b.length;
			reStr += tempChar[kk];
		}
		if (toCount == reInt || (toCount == reInt - 1))
			reStr += more;
		return reStr;
	}//System.out.println(substring("如果字符串caace爽肤水水电费是否ttt",10,"..."));

	/**     
	 *  转换字符串的内码    
	 *  @param input     输入的字符串     
	 *  @param sourceEncoding     源字符集名称     
	 *  @param targetEncoding     目标字符集名称     
	 *  @return 转换结果, 如果有错误发生, 则返回原来的值     */
	public static String changeEncoding(String input, String sourceEncoding, String targetEncoding) {
		if (input == null || input.equals(""))
			return input;
		try {
			byte[] bytes = input.getBytes(sourceEncoding);
			return new String(bytes, targetEncoding);
		} catch (Exception ex) {
		}
		return input;
	}

	/**获得输入字符串的字节长度(即二进制字节数), 用于发送短信时判断是否超出长度.     
	 * @param input     输入字符串     
	 * @return 字符串的字节长度(不是 Unicode 长度)     */
	public static int getBytesLength(String input) {
		if (input == null) {
			return 0;
		}
		int bytesLength = input.getBytes().length;
		//System.out.println("bytes length is:" + bytesLength);  
		return bytesLength;
	}

	public static String objectToString(Object in) {
		if (in != null) {
			if (in instanceof String) {
				return (String) in;
			} else {
				return "" + in.toString();
			}
		} // end if
		return null;
	}

	/**
	 * This method takes a string, removes the last instance of 
	 * a substring and returns the result.  For instance,
	 * <code>removeLastInstanceOf("ladeedadee", "dee")</code>
	 * returns "ladeeda" (not "ladadee" or "lada").
	 * 
	 * @param data String to manipulate
	 * @param instance Substring to remove
	 * @return Modified string
	 */
	public static String removeLastInstanceOf(String data, String instance) {
		if (data.lastIndexOf(instance) < 0)
			return data;
		if ((data.lastIndexOf(instance) + instance.length()) == data.length())
			return data.substring(0, data.lastIndexOf(instance));
		return data.substring(0, data.lastIndexOf(instance)).concat(
				data.substring(data.lastIndexOf(instance) + instance.length()));

	}

	/**
	 * Creates a new <code>String</code> object, containing the elements of a
	 * supplied <code>Collection</code> of <code>String</code> objects joined
	 * by a given seperator.
	 *
	 * @param collection The <code>Collection</code> containing the elements
	 * to join.
	 * @param seperator The seperator used to join the string elements.
	 * @return A new <code>String</code> with the join result.
	 * @since 1.0
	 */
	@SuppressWarnings("unchecked")
	public static String join(Collection collection, String seperator) {
		if (null == collection)
			return null;
		if (null == seperator)
			seperator = "";
		if (collection.isEmpty())
			return "";
		else {
			StringBuilder result = new StringBuilder();
			for (Object element : collection) {
				result.append(String.valueOf(element));
				result.append(seperator);
			}
			result.setLength(result.length() - seperator.length());
			return result.toString();
		}
	}

	/**
	 * Matches a collection of regular expressions against a string.
	 *
	 * @param value The <code>String</code> that will be checked.
	 * @param regexps The collection of regular expressions against which the
	 * match will be performed.
	 * @return The <code>Matcher</code> instance that corresponds to the
	 * <code>String</code> that returned a successful match; or
	 * <p><code>null</code> if no match could be found.
	 * @since 1.0
	 */
	public static Matcher getMatchingRegexp(String value, Collection<Pattern> regexps) {
		if (value != null && value.length() > 0 && regexps != null && regexps.size() > 0) {
			Matcher matcher = null;
			for (Pattern regexp : regexps) {
				matcher = regexp.matcher(value);
				if (matcher.matches()) {
					return matcher;
				}
			}
		}

		return null;
	}

	/**
	 * Checks if the name filters through an including and an excluding
	 * regular expression.
	 *
	 * @param name The <code>String</code> that will be filtered.
	 * @param included The regular expressions that needs to succeed
	 * @param excluded The regular expressions that needs to fail
	 * @return <code>true</code> if the name filtered through correctly; or
	 * <p><code>false</code> otherwise.
	 * @since 1.0
	 */
	public static boolean filter(String name, Pattern included, Pattern excluded) {
		Pattern[] included_array = null;
		if (included != null) {
			included_array = new Pattern[] { included };
		}

		Pattern[] excluded_array = null;
		if (excluded != null) {
			excluded_array = new Pattern[] { excluded };
		}

		return filter(name, included_array, excluded_array);
	}

	public static boolean notContains(String str, String searchStr) {

		return !contains(str, searchStr);
	}

	public static boolean notContains(String str, String searchStr, boolean casei) {
		if (casei)
			return !contains(str, searchStr);
		return notContainsIgnoreCase(str, searchStr);

	}

	public static boolean contains(String str, String searchStr, boolean casei) {
		if (casei)
			return contains(str, searchStr);
		return containsIgnoreCase(str, searchStr);
	}

	public static boolean notContainsIgnoreCase(String str, String searchStr) {

		return !containsIgnoreCase(str, searchStr);
	}

	/**
	 * 希望包含included同时不包含excluded
	 * @param str
	 * @param included
	 * @param excluded
	 * @param caseIgnore 忽略大小写 true=不忽略 
	 * @return
	 */
	public static boolean filter(String str, String[] included, String[] excluded, boolean caseIgnore) {
		if (null == str) {
			return false;
		}

		boolean accepted = false;

		// retain only the includes
		if (null == included) {
			accepted = true;
		} else {
			for (String search : included) {
				if (notContains(str, search, caseIgnore))
					return accepted;
			}
			accepted = true;
		}

		// remove the excludes
		if (accepted && excluded != null) {
			for (String search : excluded) {
				if (contains(str, search, caseIgnore)) {
					accepted = false;
					break;
				}
			}
		}

		return accepted;
	}

	public static boolean contansAnyIgnoreCase(String str, String[] included) {
		if (included == null)
			return true;
		boolean flag = false;
		for (String in : included) {
			if (containsIgnoreCase(str, in)) {
				flag = true;
				break;
			}
		}
		return flag;
	}

	public static boolean contansAny(String str, String[] included) {
		if (included == null)
			return true;
		boolean flag = false;
		for (String in : included) {
			if (contains(str, in)) {
				flag = true;
				break;
			}
		}
		return flag;
	}

	public static boolean contansAll(String str, String[] included) {
		return filter(str, included, null, true);
	}

	/**
	 * Checks if the name filters through a series of including and excluding
	 * regular expressions.
	 *
	 * @param name The <code>String</code> that will be filtered.
	 * @param included An array of regular expressions that need to succeed
	 * @param excluded An array of regular expressions that need to fail
	 * @return <code>true</code> if the name filtered through correctly; or
	 * <p><code>false</code> otherwise.
	 * @since 1.0
	 */
	public static boolean filter(String name, Pattern[] included, Pattern[] excluded) {
		if (null == name) {
			return false;
		}

		boolean accepted = false;

		// retain only the includes
		if (null == included) {
			accepted = true;
		} else {
			for (Pattern pattern : included) {
				if (pattern != null && pattern.matcher(name).matches()) {
					accepted = true;
					break;
				}
			}
		}

		// remove the excludes
		if (accepted && excluded != null) {
			for (Pattern pattern : excluded) {
				if (pattern != null && pattern.matcher(name).matches()) {
					accepted = false;
					break;
				}
			}
		}

		return accepted;
	}

	/**
	 * Splits a string into different parts, using a seperator string to
	 * detect the seperation boundaries in a case-sensitive manner. The
	 * seperator will not be included in the list of parts.
	 *
	 * @param source The string that will be split into parts.
	 * @param seperator The seperator string that will be used to determine
	 * the parts.
	 * @return An <code>ArrayList</code> containing the parts as
	 * <code>String</code> objects.
	 * @since 1.0
	 */
	public static ArrayList<String> splitToArrayList(String source, String seperator) {
		return splitToArrayList(source, seperator, true);
	}

	/**
	 * Splits a string into different parts, using a seperator string to
	 * detect the seperation boundaries. The seperator will not be included in
	 * the list of parts.
	 *
	 * @param source The string that will be split into parts.
	 * @param seperator The seperator string that will be used to determine
	 * the parts.
	 * @param matchCase A <code>boolean</code> indicating if the match is
	 * going to be performed in a case-sensitive manner or not.
	 * @return An <code>ArrayList</code> containing the parts as
	 * <code>String</code> objects.
	 * @since 1.0
	 */
	public static ArrayList<String> splitToArrayList(String source, String seperator, boolean matchCase) {
		ArrayList<String> substrings = new ArrayList<String>();

		if (null == source) {
			return substrings;
		}

		if (null == seperator) {
			substrings.add(source);
			return substrings;
		}

		int current_index = 0;
		int delimiter_index = 0;
		String element = null;

		String source_lookup_reference = null;
		if (!matchCase) {
			source_lookup_reference = source.toLowerCase();
			seperator = seperator.toLowerCase();
		} else {
			source_lookup_reference = source;
		}

		while (current_index <= source_lookup_reference.length()) {
			delimiter_index = source_lookup_reference.indexOf(seperator, current_index);

			if (-1 == delimiter_index) {
				element = new String(source.substring(current_index, source.length()));
				substrings.add(element);
				current_index = source.length() + 1;
			} else {
				element = new String(source.substring(current_index, delimiter_index));
				substrings.add(element);
				current_index = delimiter_index + seperator.length();
			}
		}

		return substrings;
	}

	/**
	*
	* @param from source <code>String</code> for quoted string
	* @param start character that starts quoted string
	* @param end character that ends quoted string
	* @return new <code>String</code> containing the quoted string 
	* inside <code>from</code> that starts with the character 
	* <code>start</code> and ends with <code>end</code>
	*/
	public static String quotedString(String from, char start, char end) {
		int startPos = from.indexOf(start);
		int endPos = from.indexOf(end);

		if (startPos > endPos)
			return null;

		if (startPos == -1) //  start not found
			return null;
		else if (endPos == -1)
			return null;
		else
			return from.substring(startPos, endPos + 1);

	}

	/**
	 * Returns substring following last occurrence of a char.
	 * If no occurrence of char, return the entire string.
	 */
	public static final String afterLast(String from, char ch) {
		int lastPos = from.lastIndexOf(ch);
		if (lastPos == -1)
			return from;
		else
			return from.substring(lastPos + 1, from.length());

	}

	/**
	*      Return the text which appears before the specified String.
	*      If the String does not appear, then this returns "".
	*/
	public static String before(String str, String beforeThis) {
		int o = indexOf(str, beforeThis);
		if (o == -1)
			throw new RuntimeException("String \"" + beforeThis + "\" not found");
		return substring(str, 0, o);
	}

	/**
	 * Concatenates a Collection into a String, by concatenating together the String
	 * representations of each object in the collection.
	 *
	 * @param p_coll the collection to be concatenated.
	 *
	 * @return a single String which consists of the String representations of the
	 * objects from the collection, concatenated together.
	 */
	public static String concat(Collection<?> p_coll) {
		StringBuffer buffer = new StringBuffer();

		for (Object object : ListUtils.iterable(p_coll)) {
			buffer.append(object);
		}
		return buffer.toString();
	}

	public static boolean get(String value, boolean defaultValue) {
		if (isNotNullStr(value))
			try {
				value = value.trim();

				if (value.equalsIgnoreCase(_BOOLEANS[0]) || value.equalsIgnoreCase(_BOOLEANS[1])
						|| value.equalsIgnoreCase(_BOOLEANS[2]) || value.equalsIgnoreCase(_BOOLEANS[3])
						|| value.equalsIgnoreCase(_BOOLEANS[4])) {

					return true;
				} else {
					return false;
				}
			} catch (Exception e) {
			}

		return defaultValue;

	}

	/**
	*  Servers as a 'toString()' method for objects that contain
	*  'getter' methods.
	*
	*  @param      Object  obj
	*  @return     String
	*  @exception  Exception
	*/
	public static String getToString(Object obj) {
		StringBuffer toString = new StringBuffer();
		String methodName = null;
		try {
			Class myClass = obj.getClass();

			Method[] methods = myClass.getDeclaredMethods();
			int count = methods.length;

			Method method = null;
			methodName = null;
			Object value = null;

			for (int i = 0; i < count; i++) {
				method = methods[i];
				methodName = method.getName();

				// use only 'getter' methods with no parameters
				if (methodName.substring(0, 3).equals("get") && method.getParameterTypes().length == 0) {
					//                                      log.debug( "==> methodName=" + methodName );
					//                  returnType = method.getReturnType();
					try {
						value = method.invoke(obj, null);
					} catch (InvocationTargetException e) {
						toString.append("I'm sorry  :-(  I cannot perform toString() for " + obj.getClass().getName()
								+ " object, method name: " + methodName);
					}
					//                  log.debug( "==> value=" + value );
					toString.append(System.getProperty("line.separator")).append("[").append(methodName).append("()=")
							.append(value).append("]");
				}// if
			}// for
		} catch (Exception e) {
			log.debug("ERROR :: Exception thrown:\n" + e + " :: cause ::  " + e.getMessage());
			//            toString.setLength( 0 );
			toString.append("I'm sorry  :-(  I cannot perform toString() for " + obj.getClass().getName()
					+ " object, method name: " + methodName);
		}
		return toString.toString();
	}// getToString()

	/**
	 * <p>Return <code>true</code> if the specified object is a String or
	 * a <code>null</code> value.</p>
	 *
	 * @param obj Object to be tested
	 */
	public static boolean isString(Object obj) {
		if (obj == null) {
			return (true);
		}
		return (String.class.isInstance(obj));
	}// isString()

	/**********************************
	*
	*  :: STRING VALIDATION METHODS ::
	*
	**********************************/

	public static boolean isAlphaNumeric(String str) {
		if (str == null || str.trim().length() < 1) {
			return false;
		}

		char[] charArray = str.toCharArray();
		int count = charArray.length;
		char ch;
		for (int i = 0; i < count; i++) {
			ch = charArray[i];
			// exit if invalid
			if (!Character.isLetterOrDigit(ch)) {
				return false;
			}
		}// for

		return true;// valid
	}// isAlphaNumeric()

	public static boolean isAlpha(String str) {
		if (str == null || str.trim().length() < 1) {
			return false;
		}

		char[] charArray = str.toCharArray();
		int count = charArray.length;
		char ch;
		for (int i = 0; i < count; i++) {
			ch = charArray[i];
			// exit if invalid
			if (!Character.isLetter(ch)) {
				return false;
			}
		}// for

		return true;// valid
	}// isAlphaNumeric()

	private static final float KBYTES = 1024f;
	private static final float MBYTES = KBYTES * KBYTES;
	private static final float GBYTES = MBYTES * KBYTES;

	public static String displayBytesSize(final long n) {
		final String size;
		final long abs = Math.abs(n);
		if (abs < KBYTES) {
			size = n + " bytes";
		} else if (abs < MBYTES) {
			size = String.format("%.2f", n / KBYTES) + " kB";
		} else if (abs < GBYTES) {
			size = String.format("%.2f", n / MBYTES) + " MB";
		} else {
			return String.format("%.2f", n / GBYTES) + " GB";
		}
		return size;
	}

	public static int indexOf(final String str, final char ch, final int nth) {
		if (nth < 1) {
			throw new IllegalArgumentException("nth must be greater than 0: " + nth);
		}
		int startPos = 0;
		for (int i = 0; i < nth; i++) {
			startPos = str.indexOf(ch, startPos);
			if (startPos == -1) {
				return -1;
			}

		}
		return startPos;
	}

	public static int[] indexOfanywhere(final String str, final String e) {
		int[] posArr = new int[] {};
		int pos = 0;
		for (;;) {
			pos = str.indexOf(e, pos);
			if (pos == -1)
				break;
			else
				posArr = ArrayUtils.add(posArr, pos);
			pos += e.length();
		}
		return posArr;
	}

	public static int[] lastIndexOfanywhere(final String str, final String e) {
		int[] posArr = new int[] {};
		int pos = str.length();
		for (;;) {
			pos = str.lastIndexOf(e, pos);
			if (pos == -1)
				break;
			else {

				posArr = ArrayUtils.add(posArr, pos);

			}
			pos -= e.length();
		}
		return posArr;
	}

	public static boolean hasText(String str) {
		return hasText(((CharSequence) (str)));
	}

	public static boolean hasText(CharSequence str) {
		if (!hasLength(str))
			return false;
		int strLen = str.length();
		for (int i = 0; i < strLen; i++)
			if (!Character.isWhitespace(str.charAt(i)))
				return true;

		return false;
	}

	/**
	* 压缩字符串中的空格
	*
	* @param s
	* @return
	*/
	public static String compressSpace(String s) {
		if (s != null && s.length() > 0) {
			char[] charArray = s.toCharArray();
			int len = s.length();
			StringBuffer sb = new StringBuffer("");
			int pos = 0;
			for (int i = 0; i < len; i++) {
				char c = charArray[i];
				if (c == ' ') {
					if (pos > 1) {
					}
					if (pos > 1 && charArray[i - 1] != ' ') {
						sb.append(' ');
						pos++;
					}
				} else {
					sb.append(c);
					pos++;
				}
			}
			return sb.toString();
		}
		return s;
	}

	/**
	 * 得到一个GBK编码字符串的字节长度,一个汉字或日韩文长度为2,英文字符长度为1
	 *
	 * @param String
	 *            s ,需要得到长度的字符串(GBK编码)
	 * @return int, 得到的字符串长度
	 */
	public static int length(String s) {
		if (s == null || s.equals("")) {
			return 0;
		}
		char[] c = s.toCharArray();
		int len = 0;
		for (int i = 0; i < c.length; i++) {
			len++;
			if (!isAscii(c[i])) {
				len++;
			}
		}
		return len;
	}

	/*----------- utilities for parsing data with special formats -----------*/
	/**
	 * tells whether this string contains an int. If you want the int value,
	 * don't use this method, just use Integer.parseInt().
	 */
	public static boolean isInt(String string_value) {
		try {
			Integer.parseInt(string_value);
			return true;
		} catch (NumberFormatException ex) {
			return false;
		}
	}

	/**
	 * Return true if the string represents a number i.e. 7897897 if you catch
	 */
	public static boolean isNum(String str) {
		if (str == null || str.length() <= 0)
			return false;
		char[] ch = str.toCharArray();
		for (int i = 0; i < str.length(); i++)
			if (!Character.isDigit(ch[i]))
				return false;
		return true;
	}

	/**
	 * Return true if the string represents a real number i.e. 3.0897 if you
	 */
	public static boolean isNumEx(String str) {
		if (str == null || str.length() <= 0)
			return false;
		char[] ch = str.toCharArray();
		for (int i = 0, comcount = 0; i < str.length(); i++) {
			if (!Character.isDigit(ch[i]))
				if (ch[i] != '.')
					return false;
				else if (i == 0 || i == str.length() - 1)
					return false; // .12122 or 423423. is not a real number
				else if (++comcount > 1)
					return false; // 12.322.23 is not a real number
		}
		return true;
	}

	public static boolean isVisibleChar(byte asc) {
		if (((asc >= 48) && (asc <= 57)) || ((asc >= 65) && (asc <= 90)) || ((asc >= 97) && (asc <= 122))
				|| (asc == 95)) {
			return true;
		}
		return false;
	}

	/**
	 * Returns true if the string represents a word, i.e. every char is either
	 * a-z, A-Z, 0-9, _.
	 */
	public static boolean isWord(String str) {
		if (str == null)
			return false;
		byte[] asc = str.getBytes();
		for (int i = 0; i < asc.length; i++) {
			if (!isVisibleChar(asc[i])) {
				return false;
			}
		}
		return true;
	}

	/**
	 * tells whether string_containing_alphanum contains only alphanumerics. If
	 * it's null or empty, returns true. Does not throw any
	 * ParseStringException.
	 */
	public static boolean isAlphanum(String string_containing_alphanum) {
		if (string_containing_alphanum == null || string_containing_alphanum.equals(""))
			return true;
		char[] ch = string_containing_alphanum.toCharArray();
		for (int i = 0; i < ch.length; i++)
			if (!Character.isLetterOrDigit(ch[i]))
				return false;
		return true;
	}

	/**
	 * 判断一个字符是Ascill字符还是其它字符（如汉，日，韩文字符）
	 *
	 * @param c
	 *            需要判断的字符
	 * @return boolean, 返回true,Ascii字符
	 */
	public static boolean isAscii(char c) {
		int k = 0x80;
		return c / k == 0 ? true : false;
	}

	/**
	 * tells whether string_containing_digits contains only digits. if it's null
	 * or empty, returns true. Does not throw any ParseStringException.
	 */
	public static boolean isDigits(String string_containing_digits) {
		if (string_containing_digits == null || string_containing_digits.equals(""))
			return true;
		char[] ch = string_containing_digits.toCharArray();
		for (int i = 0; i < ch.length; i++)
			if (!Character.isDigit(ch[i]))
				return false;
		return true;
	}

	@SuppressWarnings("unchecked")
	public static String join(String seperator, Iterator objects) {
		StringBuffer buf = new StringBuffer();
		if (objects.hasNext())
			buf.append(objects.next());
		while (objects.hasNext()) {
			buf.append(seperator).append(objects.next());
		}
		return buf.toString();
	}

	/**
	*      Insert a string before the specified index.
	*/
	public static String insertAt(String str, int index, String insertThis) {
		int count = str.length();
		;
		char[] buffer = str.toCharArray();
		// create temporaries
		int iCount = insertThis.length();
		int newCount = count + iCount;
		char newBuffer[] = new char[newCount];
		// copy first part of original string
		for (int i = 0; i < index; i++)
			newBuffer[i] = buffer[i];
		// copy inserted string
		for (int i = 0; i < iCount; i++)
			newBuffer[index + i] = insertThis.charAt(i);
		// copy last part of original string
		for (int i = index; i < count; i++)
			newBuffer[iCount + i] = buffer[i];
		// save new string
		buffer = newBuffer;
		count = newCount;
		return new String(buffer);
	}

	/**
	 *      Insert a string before first instance of a string.
	 */
	public static String insertBefore(String str, String beforeThis, String insertThis) {
		int o = indexOf(str, beforeThis);
		if (o == -1)
			throw new RuntimeException("String \"" + beforeThis + "\" not found");
		return insertAt(str, o, insertThis);
	}

	/**
	 *      Insert a string before last instance of a string.
	 */
	public static String insertBeforeLast(String str, String beforeThis, String insertThis) {
		int o = lastIndexOf(str, beforeThis);
		if (o == -1)
			throw new RuntimeException("String \"" + beforeThis + "\" not found");
		return insertAt(str, o, insertThis);
	}

	/**
	 *      Insert a string after first instance of a string.
	 */
	public static String insertAfter(String str, String afterThis, String insertThis) {
		int o = indexOf(str, afterThis);
		if (o == -1)
			throw new RuntimeException("String \"" + afterThis + "\" not found");
		return insertAt(str, o + afterThis.length(), insertThis);
	}

	/**
	 *      Insert a string after last instance of a string.
	 */
	public static String insertAfterLast(String str, String afterThis, String insertThis) {
		int o = lastIndexOf(str, afterThis);
		if (o == -1)
			throw new RuntimeException("String \"" + afterThis + "\" not found");
		return insertAt(str, o + afterThis.length(), insertThis);
	}

	/**
	*      Replace the text between two strings with another string.
	*/
	public static String replaceBetween1(String str, String afterThis, String beforeThis, String withThis) {
		int count = str.length();
		char[] buffer = str.toCharArray();
		int startingIndex = indexOf(str, afterThis);
		if (startingIndex == -1)
			throw new RuntimeException("String \"" + afterThis + "\" not found");
		startingIndex += afterThis.length();
		int endingIndex = indexOf(str, beforeThis, startingIndex);
		if (endingIndex == -1)
			throw new RuntimeException("String \"" + beforeThis + "\" not found");
		// create temporaries
		int rCount = endingIndex - startingIndex;
		int wCount = withThis.length();
		int nCount = count - rCount + wCount;
		char newBuffer[] = new char[nCount];
		char temp[] = withThis.toCharArray(); // trash
		// copy first part
		for (int i = 0; i < startingIndex; i++)
			newBuffer[i] = buffer[i];
		// copy withThis
		for (int j = 0; j < wCount; j++)
			newBuffer[j + startingIndex] = temp[j];
		// copy last part
		for (int k = startingIndex + rCount; k < count; k++)
			newBuffer[k + wCount - rCount] = buffer[k];
		// save new string
		buffer = newBuffer;
		return new String(buffer);
	}

	/**
	 *      Replace the first occurance of a string with another string.
	 *      Special case replacements of same length and other "in buffer" operations?
	 */
	public static String replaceFirst(String str, String replaceThis, String withThis) {
		int count = str.length();
		char[] buffer = str.toCharArray();
		int o = indexOf(str, replaceThis);
		if (o == -1)
			throw new RuntimeException("String \"" + replaceThis + "\" not found");
		// create temporaries
		int rCount = replaceThis.length();
		int wCount = withThis.length();
		int nCount = count - rCount + wCount;
		char newBuffer[] = new char[nCount];
		char temp[] = withThis.toCharArray(); // trash
		// copy first part
		for (int i = 0; i < o; i++)
			newBuffer[i] = buffer[i];
		// copy withThis
		for (int j = 0; j < wCount; j++)
			newBuffer[j + o] = temp[j];
		// copy last part
		for (int k = o + rCount; k < count; k++)
			newBuffer[k + wCount - rCount] = buffer[k];
		// save new string
		return new String(newBuffer);
	}

	/**
	 *      Replace the last occurance of a string with another string.
	 */
	public static String replaceLast(String str, String replaceThis, String withThis) {
		int count = str.length();
		char[] buffer = str.toCharArray();
		int o = lastIndexOf(str, replaceThis);
		if (o == -1)
			throw new RuntimeException("String \"" + replaceThis + "\" not found");
		// create temporaries
		int rCount = replaceThis.length();
		int wCount = withThis.length();
		int nCount = count - rCount + wCount;
		char newBuffer[] = new char[nCount];
		char temp[] = withThis.toCharArray(); // trash
		// copy first part
		for (int i = 0; i < o; i++)
			newBuffer[i] = buffer[i];
		// copy withThis
		for (int j = 0; j < wCount; j++)
			newBuffer[j + o] = temp[j];
		// copy last part
		for (int k = o + rCount; k < count; k++)
			newBuffer[k + wCount - rCount] = buffer[k];
		// save new string
		return new String(newBuffer);
	}

	/**
	 *      Delete a specified range of characters.
	 */
	public static String delete(String str, int startingIndex, int endingIndex) {
		int count = str.length();
		char[] buffer = str.toCharArray();
		// examine error conditions
		if (startingIndex > count)
			throw new RuntimeException("Bad startingIndex specified.");
		if (endingIndex > count)
			throw new RuntimeException("Bad endingIndex specified.");
		// ignore negative ranges - don't throw
		if (startingIndex > endingIndex)
			return str;
		// create temporaries
		int dCount = endingIndex - startingIndex + 1;
		char newBuffer[] = new char[count - dCount];
		// copy first part
		for (int i = 0; i < startingIndex; i++)
			newBuffer[i] = buffer[i];
		// copy last part
		for (int i = endingIndex + 1; i < count; i++)
			newBuffer[i - dCount] = buffer[i];
		// save new string
		return new String(newBuffer);
	}

	/**
	 *      Delete the first occurance of a substring.
	 */
	public static String deleteFirst(String str, String deleteThis) {
		return replaceFirst(str, deleteThis, "");
	}

	/**
	 *      Delete the last occurance of the specified string.
	 */
	public static String deleteLast(String str, String deleteThis) {
		return replaceLast(str, deleteThis, "");
	}

	/**
	 *      Delete every occurance of the specified string.
	 */
	public static String deleteAll(String str, String deleteThis) {
		return replaceAll(str, deleteThis, "");
	}

	/**
	 *      Replace all instances of a string with another string.
	 */
	public static String replaceAll(String str, String replaceThis, String withThis) {
		int count = str.length();
		char[] buffer = str.toCharArray();
		int o;
		int startAt = 0;
		String tmpString = new String(str);
		while ((o = indexOf(tmpString, replaceThis, startAt)) != -1) {
			// create temporaries
			int rCount = replaceThis.length();
			int wCount = withThis.length();
			int nCount = count - rCount + wCount;
			char newBuffer[] = new char[nCount];
			char temp[] = withThis.toCharArray(); // trash
			// copy first part
			for (int i = 0; i < o; i++)
				newBuffer[i] = buffer[i];
			// copy withThis
			for (int j = 0; j < wCount; j++)
				newBuffer[j + o] = temp[j];
			// copy last part
			for (int k = o + rCount; k < count; k++)
				newBuffer[k + wCount - rCount] = buffer[k];
			// set new starting point for next offset search
			startAt = o + wCount;
			// save new string
			buffer = newBuffer;
			count = nCount;
			tmpString = new String(buffer);
		}
		// save new string
		return new String(buffer);
	}

	/**
	 *      Delete everything before the specified string.
	 */
	public static String deleteBefore(String str, String beforeThis) {
		int o = indexOf(str, beforeThis);
		if (o == -1)
			throw new RuntimeException("String \"" + beforeThis + "\" not found");
		return delete(str, 0, o - 1);
	}

	/**
	 *      Delete everything after the specified string.
	 */
	public static String deleteAfter(String str, String afterThis) {
		int count = str.length();
		int o = indexOf(str, afterThis);
		if (o == -1)
			throw new RuntimeException("String \"" + afterThis + "\" not found");
		return delete(str, o + afterThis.length(), count - 1);
	}

	/**
	 *      Delete the string between two strings.
	 */
	public static String deleteBetween(String str, String afterThis, String beforeThis) {
		int startingIndex = indexOf(str, afterThis);
		if (startingIndex == -1)
			throw new RuntimeException("String \"" + afterThis + "\" not found");
		startingIndex += afterThis.length();
		int endingIndex = indexOf(str, beforeThis, startingIndex);
		if (endingIndex == -1)
			throw new RuntimeException("String \"" + beforeThis + "\" not found");
		return delete(str, startingIndex, endingIndex - 1);
	}

	/**
	 *      Keep on the text before a string (or delete the string and everything after it).
	 */
	public static String keepBefore(String str, String beforeThis) {
		int count = str.length();

		int o = indexOf(str, beforeThis);
		if (o == -1)
			throw new RuntimeException("String \"" + beforeThis + "\" not found");
		return delete(str, o, count - 1);
	}

	/**
	 *      Keep the text after a string (or delete the string and everything before it).
	 */
	public static String keepAfter(String str, String afterThis) {
		int o = indexOf(str, afterThis);
		if (o == -1)
			throw new RuntimeException("String \"" + afterThis + "\" not found");
		return delete(str, 0, o + afterThis.length() - 1);
	}

	/**
	 *      Keep only the text between two strings.
	 */
	public static String keepBetween(String str, String afterThis, String beforeThis) {
		int count = str.length();
		char[] buffer = str.toCharArray();
		int startingIndex = indexOf(str, afterThis);
		if (startingIndex == -1)
			throw new RuntimeException("String \"" + afterThis + "\" not found");
		startingIndex += afterThis.length();
		int endingIndex = indexOf(str, beforeThis, startingIndex);
		if (endingIndex == -1)
			throw new RuntimeException("String \"" + beforeThis + "\" not found");
		// create temporaries
		int nCount = endingIndex - startingIndex;
		char newBuffer[] = new char[nCount];
		// copy characters which remain
		for (int i = startingIndex; i < endingIndex; i++)
			newBuffer[i - startingIndex] = buffer[i];
		// save new buffer
		return new String(newBuffer);
	}

	/**
	 *      Return the number of strings (tokens) seperated by the specified token.
	 */
	public static int countTokens(String str, String token) {
		// count the number of tokens
		int tLength = token.length();
		int tCount = 0;
		int startAt = 0;
		while (true) {
			int o = indexOf(str, token, startAt);
			if (o == -1)
				break;
			tCount++;
			startAt = o + tLength;
		}
		return tCount + 1;
	}

	/**
	 *      Return an array of strings seperated by the specified token.
	 *      The token will not appear in the strings.
	 */
	public static String[] tokens(String str, String token) {
		if (isEmpty(str))
			return new String[] {};
		int tCount = countTokens(str, token);
		// create array for tokens
		String tokens[] = new String[tCount];
		// make a temporary CoolString to peel apart
		String temp = new String(str);
		// get all the substrings
		for (int j = 0; j < tCount; j++) {
			// the last token won't have a token terminator
			if (j == tCount - 1)
				tokens[j] = temp.toString();
			else {
				tokens[j] = before(temp, token);
				temp = keepAfter(temp, token);
			}
		}
		return tokens;
	}

	/**
	 *      Compare a character to a character by offset, using the caseSensitive setting.
	 *      @param loc The offset to the character in this CoolString.
	 *      @param c The character to compare against.
	 */
	public static boolean equalChars(String str, int index, char c, boolean caseSensitive) {
		int count = length(str);
		char[] buffer = str.toCharArray();
		if (index >= count)
			return false;
		else if (caseSensitive)
			return buffer[index] == c;
		else
			return Character.toLowerCase(buffer[index]) == Character.toLowerCase(c);
	}

	/**
	 *      Compare to a char array.
	 */
	public static boolean equals(String str, char[] c) {
		int count = length(str);
		boolean same = c.length == count;
		int i = 0;
		while (same && i < count) {
			same = equalChars(str, i, c[i], false);
			i++;
		}
		return same;
	}

	/**
	 *      Compare to anything by converting it to a string and then a char array.
	 *      This generates too much garbage though.
	 */
	public static boolean equals(String str, Object o) {
		char c[] = o.toString().toCharArray(); // trash
		return equals(str, c);
	}

	/**
	 *      Append a string to the end of this string.
	 */
	public static String append(String str, String appendThis) {
		return insertAt(str, length(str), appendThis);
	}

	/**
	 *      Prepend a string in front of this string.
	 */
	public static String prepend(String str, String prependThis) {
		return insertAt(str, 0, prependThis);
	}

	/**
	 *      Return the string before the first token.
	 */
	public static String firstToken(String str, String token) {
		return before(str, token);
	}

	/**
	 *      Return the string after the last token.
	 */
	public static String lastToken(String str, String token) {
		int o = lastIndexOf(str, token);
		return substring(str, o + 1, length(str));
	}

	/**
	 *      Return the Nth string from a tokenized string. N is zero based.
	 */
	public static String NthToken(String str, String token, int n) {
		String[] temp = tokens(str, token);
		if (n >= temp.length)
			throw new RuntimeException("Only " + temp.length + " tokens present (try a zero based index).");
		return temp[n];
	}

	/**
	 * 根据字符串的最后来截取
	 * @param str
	 * @param open
	 * @param close
	 * @return
	 */
	public static String substringBetweenLaster(String str, String open, String close) {
		if (str == null || open == null || close == null)
			return null;
		int start = str.lastIndexOf(open);
		if (start != -1) {
			int end = str.lastIndexOf(close);
			if (end != -1)
				return str.substring(start + open.length(), end);
		}
		return null;
	}

	/**
	* 取得字符串中的所有中文
	* @param s
	* @return
	*/
	public static String getChineseString(String s) {
		Pattern pat = Pattern.compile("[^\u4e00-\u9fa5^\n]+", Pattern.DOTALL | Pattern.MULTILINE
				| Pattern.CASE_INSENSITIVE);
		Matcher m;
		if (s != null) {
			m = pat.matcher(s);
		} else {
			return null;
		}
		return m.replaceAll(" ");
	}

	public static String ltrimWhitespace(String str) {
		if (!hasLength(str))
			return str;
		StringBuilder sb = new StringBuilder(str);
		while (sb.length() > 0 && Character.isWhitespace(sb.charAt(0))) {
			sb.deleteCharAt(0);
		}
		return sb.toString();
	}

	public static String rtrimWhitespace(String str) {
		if (!hasLength(str))
			return str;
		StringBuilder sb = new StringBuilder(str);
		while (sb.length() > 0 && Character.isWhitespace(sb.charAt(sb.length() - 1))) {
			sb.deleteCharAt(sb.length() - 1);
		}
		return sb.toString();
	}

	public static String ltrimCharacter(String str, char leadingCharacter) {
		if (!hasLength(str))
			return str;
		StringBuilder sb = new StringBuilder(str);
		while (sb.length() > 0 && sb.charAt(0) == leadingCharacter) {
			sb.deleteCharAt(0);
		}
		return sb.toString();
	}

	public static String rtrimCharacter(String str, char trailingCharacter) {
		if (!hasLength(str))
			return str;
		StringBuilder sb = new StringBuilder(str);
		while (sb.length() > 0 && sb.charAt(sb.length() - 1) == trailingCharacter) {
			sb.deleteCharAt(sb.length() - 1);
		}
		return sb.toString();
	}

	public static boolean startsWithIgnoreCase(String str, String prefix) {
		if (str == null || prefix == null)
			return false;
		if (str.startsWith(prefix))
			return true;
		if (str.length() < prefix.length())
			return false;
		String lcStr = str.substring(0, prefix.length()).toLowerCase();
		String lcPrefix = prefix.toLowerCase();
		return lcStr.equals(lcPrefix);
	}

	public static boolean endsWithIgnoreCase(String str, String suffix) {
		if (str == null || suffix == null)
			return false;
		if (str.endsWith(suffix))
			return true;
		if (str.length() < suffix.length())
			return false;
		String lcStr = str.substring(str.length() - suffix.length()).toLowerCase();
		String lcSuffix = suffix.toLowerCase();
		return lcStr.equals(lcSuffix);
	}

	public static int indexOfIgnoreCase(String str, String s) {
		if (str == null || s == null)
			return -1;
		if (str.length() < s.length())
			return -1;
		int pos = str.indexOf(s);
		if (pos > -1)
			return pos;
		return str.toLowerCase().indexOf(s.toLowerCase());
	}

	public static int lastIndexOfIgnoreCase(String str, String s) {
		if (str == null || s == null)
			return -1;
		if (str.length() < s.length())
			return -1;
		int pos = str.indexOf(s);
		if (pos > -1)
			return pos;
		return str.toLowerCase().lastIndexOf(s.toLowerCase());
	}

	public static boolean substringMatch(CharSequence str, int index, CharSequence substring) {
		for (int j = 0; j < substring.length(); j++) {
			int i = index + j;
			if (i >= str.length() || str.charAt(i) != substring.charAt(j)) {
				return false;
			}
		}
		return true;
	}

	public static int countOccurrencesOf(String str, String sub) {
		if (str == null || sub == null || str.length() == 0 || sub.length() == 0) {
			return 0;
		}
		int count = 0, pos = 0, idx = 0;
		while ((idx = str.indexOf(sub, pos)) != -1) {
			++count;
			pos = idx + sub.length();
		}
		return count;
	}

	public static String deleteAny(String str, String charsToDelete) {
		if (!hasLength(str) || !hasLength(charsToDelete)) {
			return str;
		}
		StringBuilder sb = new StringBuilder();
		for (int i = 0; i < str.length(); i++) {
			char c = str.charAt(i);
			if (charsToDelete.indexOf(c) == -1) {
				sb.append(c);
			}
		}
		return sb.toString();
	}

	public static String mark(String str, char c) {
		return str == null ? null : c + str + c;
	}

	public static String mark(String str, String s) {
		return str == null ? null : new StringBuilder(str.length() + s.length() * 2).append(s).append(str).append(s)
				.toString();
	}

	/**
	 * Quote the given String with single quotes.
	 * @param str the input String (e.g. "myString")
	 * @return the quoted String (e.g. "'myString'"),
	 * or <code>null<code> if the input was <code>null</code>
	 */
	public static String quote(String str) {
		return (str != null ? "'" + str + "'" : null);
	}

	/**
	 * Turn the given Object into a String with single quotes
	 * if it is a String; keeping the Object as-is else.
	 * @param obj the input Object (e.g. "myString")
	 * @return the quoted String (e.g. "'myString'"),
	 * or the input object as-is if not a String
	 */
	public static Object quoteIfString(Object obj) {
		return (obj instanceof String ? quote((String) obj) : obj);
	}

	/**
	 * Unqualify a string qualified by a '.' dot character. For example,
	 * "this.name.is.qualified", returns "qualified".
	 * @param qualifiedName the qualified name
	 */
	public static String unqualify(String qualifiedName) {
		return unqualify(qualifiedName, '.');
	}

	/**
	 * Unqualify a string qualified by a separator character. For example,
	 * "this:name:is:qualified" returns "qualified" if using a ':' separator.
	 * @param qualifiedName the qualified name
	 * @param separator the separator
	 */
	public static String unqualify(String qualifiedName, char separator) {
		return qualifiedName.substring(qualifiedName.lastIndexOf(separator) + 1);
	}

	/**
	 * Create a line
	 *
	 * @param c
	 *            The fill char
	 * @param l
	 *            The line lenght
	 * @return The text line
	 */
	static public String line(char c, int l) {
		char[] chars = new char[l];
		Arrays.fill(chars, c);

		return new String(chars);
	}

	/**
	 * Count the occurrences of a given char in a string
	 *
	 * @param s
	 *            The char to be counted
	 * @param c
	 *            The string to be examinde
	 * @return The occurrences of a given char in a string
	 */
	static public int count(String s, char c) {
		int count = 0;

		char[] chars = s.toCharArray();
		for (char tempC : chars) {
			if (tempC == c) {
				count++;
			}
		}

		return count;
	}

	/**
	 *  判断是否全为英文字母 
	 * @param strin
	 * @return
	 */
	public static boolean IsEnglishCharacter(String strin) {
		char c;
		for (int i = 0; i < strin.length(); i++) {
			c = strin.charAt(i);
			if ((c <= 0x007A && c >= 0x0061) == false && (c <= 0x005A && c >= 0x0041) == false)
				return false;
		}
		return true;

	}
	
	public static void main(String[] args) throws Exception {
		String[] sdfStrings = new String[] {
				"Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; .NET CLR 2.0.50727; MAXTHON 2.0)",
				"Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; .NET CLR 2.0.50727; TheWorld)",
				"Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; .NET CLR 2.0.50727; GreenBrowser)",
				"Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; TencentTraveler 4.0; .NET CLR 2.0.50727)",
				"Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; .NET CLR 2.0.50727; 360SE)" };
	/*	for (String string : sdfStrings) {
			String substringBetweenLaster = StringUtils.substringBetweenLaster(string, ";", ")");
			System.out.println(string);
			System.out.println(substringBetweenLaster + ":" + (substringBetweenLaster.indexOf(".NET") < 0));
		}*/
		String str=StringUtils.trim("http://blogtd.org/'http://extra-001.yo2cdn.com/wp-includes/images/smilies-7/icon_eek.gif'", "'");
		System.out.println(str);
		

	}
}
